/*************************************************************************
|                                                                        |
|   MTIME.C                                                     10.06.93 |
|   ADMAKE Utility:  compiler-specific time functions                    |
|                                                                        |
*************************************************************************/

/*************************************************************************
|                                                                        |
|   Important note:  ADMAKE stores date/time values in two different     |
|   ways depending on which compiler is in use:                          |
|                                                                        |
|   BORLAND, VMS               :   Date/time held in DOS file format     |
|   MSC(DOS), WATCOM,                (ADMAKE_FTIME is #defined)          |
|   INTEL, ZORTECH                                                       |
|                                                                        |
|   UNIX, MSC(OS/2), Coherent  :   Date/time held in 'Unix' format       |
|   BORLAND(OS/2)                                                        |
|                                                                        |
|   The VMS routines have been adapted from the FILE utility, written    |
|   by Joe Meadows Jr.  The PD source for this utility can be found      |
|   on BIX.                                                              |
|                                                                        |
*************************************************************************/

/*************************************************************************
|                                                                        |
|   This module implements the following functions:                      |
|                                                                        |
|   modtime    :  get the modification time of a file, 0 if not found    |
|   curtime    :  return current time in suitable format                 |
|   touch      :  update the time of a file to now                       |
|   dodisp     :  display a file time                                    |
|   alltime    :  get the modification time of all files matching spec.  |
|                                                                        |
*************************************************************************/

#ifdef VMS
#define ADMAKE_FTIME 1
#include STDIO
#include "h.h"
#include DESCRIP
#include RMS
#include ERRNO
#include CTYPE
#include STRING
#include STDLIB
#include TYPES
#include TIME

#define ATR$C_UCHAR 3
#define ATR$C_RECATTR 4
#define ATR$C_ASCDATES 13
#define ATR$C_CREDATE 17
#define ATR$C_REVDATE 18
#define ATR$C_EXPDATE 19
#define ATR$C_BAKDATE 20
#define ATR$C_JOURNAL 29

struct ATRDEF
{
  unsigned short int atr$w_size;
  unsigned short int atr$w_type;
  unsigned char *atr$l_addr;
};

struct FATDEF  {
  variant_union  {
    unsigned char fat$b_rtype;
    variant_struct  {
      unsigned fat$v_rtype : 4;
      unsigned fat$v_fileorg : 4;
    } fat$r_rtype_bits;
  } fat$r_rtype_overlay;
  variant_union  {
    unsigned char fat$b_rattrib;
    variant_struct  {
      unsigned fat$v_fortrancc : 1;
      unsigned fat$v_impliedcc : 1;
      unsigned fat$v_printcc : 1;
      unsigned fat$v_nospan : 1;
    } fat$r_rattrib_bits;
  } fat$r_rattrib_overlay;
  unsigned short int fat$w_rsize;
  variant_union
  {
    unsigned long int fat$l_hiblk;
    variant_struct
    {
      unsigned short int fat$w_hiblkh;
      unsigned short int fat$w_hiblkl;
    } FATDEF$DUMMY_0;
  } FATDEF$DUMMY_1;
  variant_union
  {
    unsigned long int fat$l_efblk;
    variant_struct
    {
      unsigned short int fat$w_efblkh;
      unsigned short int fat$w_efblkl;
    } FATDEF$DUMMY_2;
  } FATDEF$DUMMY_3;
  unsigned short int fat$w_ffbyte;
  unsigned char fat$b_bktsize;
  unsigned char fat$b_vfcsize;
  unsigned short int fat$w_maxrec;
  unsigned short int fat$w_defext;
  unsigned short int fat$w_gbc;
  char fat$fill[8];
  unsigned short int fat$w_versions;
};

struct fchdef  {
  unsigned : 1;
  unsigned fch$v_nobackup : 1 ;
  unsigned fch$v_writeback : 1;
  unsigned fch$v_readcheck : 1;
  unsigned fch$v_writcheck : 1;
  unsigned fch$v_contigb : 1;
  unsigned fch$v_locked : 1;
  unsigned fch$v_contig : 1;
  unsigned : 3;
  unsigned fch$v_badacl : 1;
  unsigned fch$v_spool : 1;
  unsigned fch$v_directory : 1;
  unsigned fch$v_badblock : 1;
  unsigned fch$v_markdel : 1;
  unsigned fch$v_nocharge : 1;
  unsigned fch$v_erase : 1;
};

struct fibdef {
    variant_union  {
        unsigned long int fib$l_acctl;
        variant_struct  {
            unsigned fib$v_nowrite : 1;
            unsigned fib$v_dlock : 1;
            unsigned fib$v_blk_lock : 1;
            unsigned fibdef$$_fill_1 : 1;
            unsigned fib$v_spool : 1;
            unsigned fib$v_writeck : 1;
            unsigned fib$v_seqonly : 1;
            unsigned fibdef$$_fill_2 : 1;
            unsigned fib$v_write : 1;
            unsigned fib$v_readck : 1;
            unsigned fib$v_noread : 1;
            unsigned fib$v_notrunc : 1;
            unsigned fib$v_control : 1;
            unsigned fibdef$$_fill_3 : 3;


            unsigned fib$v_execute : 1;
            unsigned fib$v_prsrv_atr : 1;
            unsigned fib$v_rmslock : 1;
            unsigned fib$v_writethru : 1;
            unsigned fib$v_nolock : 1;
            unsigned fib$v_norecord : 1;
            unsigned fibdef$$_fill_4 : 2;
            } fib$r_acctl_bits0;
        variant_struct  {
            unsigned fibdef$$_fill_5 : 3;
            unsigned fib$v_rewind : 1;
            unsigned fib$v_curpos : 1;
            unsigned fibdef$$_fill_6 : 1;
            unsigned fib$v_update : 1;
            unsigned fib$v_fill_1 : 1;
            } fib$r_acctl_bits1;
        variant_struct  {
            char fibdef$$_fill_13 [3];
            char fib$b_wsize;
            } fib$r_acctl_fields2;
        } fib$r_acctl_overlay;
    variant_union  {
        unsigned short int fib$w_fid [3];
        variant_struct  {
            unsigned short int fib$w_fid_num;
            unsigned short int fib$w_fid_seq;
            variant_union  {
                unsigned short int fib$w_fid_rvn;
                variant_struct  {
                    unsigned char fib$b_fid_rvn;
                    unsigned char fib$b_fid_nmx;
                    } fib$r_fid_rvn_fields;
                } fib$r_fid_rvn_overlay;
            } fib$r_fid_fields;
        } fib$r_fid_overlay;
    variant_union  {
        unsigned short int fib$w_did [3];
        variant_struct  {
            unsigned short int fib$w_did_num;
            unsigned short int fib$w_did_seq;
            variant_union  {
                unsigned short int fib$w_did_rvn;
                variant_struct  {
                    unsigned char fib$b_did_rvn;
                    unsigned char fib$b_did_nmx;
                    } fib$r_did_rvn_fields;
                } fib$r_did_rvn_overlay;
            } fib$r_did_fields;
        } fib$r_did_overlay;
    unsigned long int fib$l_wcc;
    variant_union  {
        unsigned short int fib$w_nmctl;
        variant_struct  {
            unsigned fibdef$$_fill_7 : 3;
            unsigned fib$v_allver : 1;
            unsigned fib$v_alltyp : 1;
            unsigned fib$v_allnam : 1;
            unsigned fibdef$$_fill_8 : 2;
            unsigned fib$v_wild : 1;
            unsigned fib$v_newver : 1;
            unsigned fib$v_supersede : 1;
            unsigned fib$v_findfid : 1;
            unsigned fibdef$$_fill_9 : 2;
            unsigned fib$v_lowver : 1;
            unsigned fib$v_highver : 1;
            } fib$r_nmctl_bits;
        } fib$r_nmctl_overlay;
    variant_union  {
        unsigned short int fib$w_exctl;
        variant_struct  {
            unsigned fib$v_alcon : 1;
            unsigned fib$v_alconb : 1;
            unsigned fib$v_filcon : 1;
            unsigned fib$v_aldef : 1;
            unsigned fib$v_allocatr : 1;
            unsigned fibdef$$_fill_10 : 2;
            unsigned fib$v_extend : 1;
            unsigned fib$v_trunc : 1;
            unsigned fib$v_nohdrext : 1;
            unsigned fib$v_markbad : 1;
            unsigned fibdef$$_fill_11 : 4;
            unsigned fib$v_nocharge : 1;
            } fib$r_exctl_bits;
        } fib$r_exctl_overlay;
    unsigned long int fib$l_exsz;
    unsigned long int fib$l_exvbn;
    variant_union  {
        unsigned char fib$b_alopts;
        variant_struct  {
            unsigned fib$v_exact : 1;
            unsigned fib$v_oncyl : 1;
            unsigned fib$v_fill_2 : 6;
            } fib$r_alopts_bits;
        } fib$r_alopts_overlay;
    unsigned char fib$b_alalign;
    variant_union  {
        unsigned short int fib$w_alloc [5];
        variant_struct  {
            variant_union  {
                unsigned short int fib$w_loc_fid [3];
                variant_struct  {
                    unsigned short int fib$w_loc_num;
                    unsigned short int fib$w_loc_seq;
                    variant_union  {
                        unsigned short int fib$w_loc_rvn;
                        variant_struct  {
                            unsigned char fib$b_loc_rvn;
                            unsigned char fib$b_loc_nmx;
                            } fib$r_loc_rvn_fields;
                        } fib$r_loc_rvn_overlay;
                    } fib$r_loc_fid_fields;
                } fib$r_loc_fid_overlay;
            unsigned long int fib$l_loc_addr;
            } fib$r_alloc_fields;
        } fib$r_alloc_overlay;
    unsigned short int fib$w_verlimit;
    unsigned char fib$b_agent_mode;
    char fibdef$$_fill_12;
    unsigned long int fib$l_aclctx;
    unsigned long int fib$l_acl_status;
    variant_union  {
        unsigned long int fib$l_status;
        variant_struct  {
            unsigned fib$v_alt_req : 1;
            unsigned fib$v_alt_granted : 1;
            unsigned fib$v_diracl : 1;
            unsigned fib$v_propagate : 1;
            unsigned fib$v_fill_3 : 4;
            } fib$r_status_bits;
        } fib$r_status_overlay;
    unsigned long int fib$l_alt_access;
    } ;

struct fjndef  {
  unsigned fjn$v_only_ru : 1;
  unsigned fjn$v_rujnl : 1;
  unsigned fjn$v_bijnl : 1;
  unsigned fjn$v_aijnl : 1;
  unsigned fjn$v_atjnl : 1;
  unsigned fjn$v_never_ru : 1;
  unsigned fjn$v_journal_file:1;
} ;

#define IO$_ACCESS 50
#define IO$_MODIFY 54
#define FIB$M_NORECORD 2097152

static struct FAB Fab;
static struct NAM Nam;
static struct fibdef Fib;   /* short fib */

static struct dsc$descriptor FibDesc =
  {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,&Fib};
static struct dsc$descriptor_s DevDesc =
  {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
static struct FATDEF Fat;
static union 
{
    struct fchdef fch;
    long int dummy;
} uuchar;
static struct fjndef jnl;
static long int Cdate[2],Rdate[2],Edate[2],Bdate[2],Modtime[2];
static short int revisions;

static struct ATRDEF Atr[] = 
{
    sizeof(Fat),ATR$C_RECATTR,&Fat,         /* record attributes */
    sizeof(uuchar),ATR$C_UCHAR,(unsigned char *)&uuchar,    /* File characteristics */
    sizeof(Cdate),ATR$C_CREDATE,(unsigned char *)&Cdate[0], /* Creation date */
    sizeof(Rdate),ATR$C_REVDATE,(unsigned char *)&Rdate[0], /* Revision date */
    sizeof(Edate),ATR$C_EXPDATE,(unsigned char *)&Edate[0], /* Expiration date */
    sizeof(Bdate),ATR$C_BAKDATE,(unsigned char *)&Bdate[0], /* Backup date */
    sizeof(revisions),ATR$C_ASCDATES,(unsigned char *)&revisions, /* number of revisions */
    sizeof(jnl),ATR$C_JOURNAL,(unsigned char *)&jnl,        /* journal flags */
    0,0,0
} ;

static char EName[NAM$C_MAXRSS];
static char RName[NAM$C_MAXRSS];
static struct dsc$descriptor_s FileName =
   {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
static short int DevChan;
static short int iosb[4];

static long int i,j,status;
static int assign_switch = 0;
static short int numtime[7];
#endif

#ifdef NIX
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef COHERENT
#include <utime.h>
#endif
#include "h.h"
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#endif

#ifdef __BORLANDC__
#ifdef PAMDOS
#define ADMAKE_FTIME 1
#define STANDARD_ALLTIME 1
#define STANDARD_MODTIME 1
#define STANDARD_TOUCH 1
#else
#include <sys\stat.h>
#include <utime.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include "h.h"
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#endif

#ifdef __ZTC__
#define ADMAKE_FTIME 1
#define _dos_setftime(x,y,z) dos_setftime(x,y,z)
#define STANDARD_ALLTIME 1
#define STANDARD_MODTIME 1
#define STANDARD_TOUCH 1
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "h.h"
#define MSDOS 1
#include <dos.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#endif 

#ifdef _MSC_VER
#ifdef PAMDOS
#define ADMAKE_FTIME 1
#define STANDARD_ALLTIME 1
#define STANDARD_MODTIME 1
#define STANDARD_TOUCH 1
#endif
#include <stdio.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <sys\utime.h>
#include <dos.h>
#include "h.h"
#include <errno.h>
#include <string.h>
#ifdef HEAP
#include <heap.h>
#endif
#include <time.h>
#endif 

#ifdef __WATCOMC__
#define ADMAKE_FTIME 1
#define STANDARD_ALLTIME 1
#define STANDARD_MODTIME 1
#define STANDARD_TOUCH 1
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <direct.h>
#include <h.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <process.h>
#include <sys\utime.h>
#include <time.h>
#endif

#ifdef _INTELC32_
#define ADMAKE_FTIME 1
#define STANDARD_ALLTIME 1
#define STANDARD_MODTIME 1
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <sys\utime.h>
#include <dos.h>
#include "h.h"
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#endif 

/*************************************************************************
|                                                                        |
|   MODTIME                                                              |
|                                                                        |
*************************************************************************/

#ifdef VMS
#define MODTIME_DONE 1

#ifdef PANEWFD
VOID modtime(struct name * np)
#else
VOID modtime(np)
struct name * np;
#endif

{
    unsigned int            lo,hi;

    if (np->n_flag & N_TSNAP) return;
    if ((np->n_name[0] == '.') && 
        (np->n_name[1] >= 'A') && 
        (np->n_name[1] <= 'Z'))
        {np->n_time = 0L; return;}

    /* initialize RMS structures, we need a NAM to retrieve the FID */
    Fab = cc$rms_fab;
    Fab.fab$l_fna = np->n_name; /* name of file */
    Fab.fab$b_fns = strlen(np->n_name);
    Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
    Nam = cc$rms_nam;
    Nam.nam$l_esa = &EName; /* expanded filename */
    Nam.nam$b_ess = sizeof(EName);
    Nam.nam$l_rsa = &RName; /* resultant filename */
    Nam.nam$b_rss = sizeof(RName);

    /* do $PARSE and $SEARCH here */
    status = sys$parse(&Fab);
    if (!(status & 1)) 
        fatal(MSG[74], dollar(np->n_name), status); /* cannot get mod time */

    /* search for the first file.. If none report zero modtime */
    status = sys$search(&Fab);
    if (!(status & 1)) {np->n_time = 0L; return;}

    /* initialize Device name length, note that this points into the NAM
       to get the device name filled in by the $PARSE, $SEARCH services */
    DevDesc.dsc$w_length = Nam.nam$t_dvi[0];

    status = sys$assign(&DevDesc,&DevChan,0,0);
    if (!(status & 1)) 
        fatal(MSG[74], dollar(np->n_name), status); /* cannot get mod time */

    FileName.dsc$a_pointer = Nam.nam$l_name;
    FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;

    /* Initialize the FIB */
    for (i = 0; i < 3; i++)
        Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
    for (i = 0; i < 3; i++)
        Fib.fib$w_did[i]=Nam.nam$w_did[i];

    /* Use the IO$_ACCESS function to return info about the file */
    /* Note, used this way, the file is not opened, and the expiration */
    /* and revision dates are not modified */
    status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
                        &FibDesc,&FileName,0,0,&Atr,0);

    if (!(status & 1))
        fatal(MSG[74], dollar(np->n_name), status); /* cannot get mod time */
    status = iosb[0];
    if (!(status & 1)) 
        fatal(MSG[74], dollar(np->n_name), status); /* cannot get mod time */

    Fab.fab$b_dns = 0;
    Nam.nam$l_rlf = 0;
    Nam.nam$b_nop |= NAM$M_SYNCHK;
    sys$parse(&Fab);

    Modtime[0] = Cdate[0];
    Modtime[1] = Cdate[1];
    if ((Rdate[0] == 0) && (Rdate[1] == 0))
    {
        Modtime[0] = Rdate[0];
        Modtime[1] = Rdate[1];
    }   
    if ((Modtime[0] == 0) && (Modtime[1] == 0)) {np->n_time = 0L; return;}

    /* convert Modtime to np->ntime (dos format) */
    sys$numtim(numtime,Modtime);
    hi = (numtime[0] - 1980) << 9;
    hi += (numtime[1] << 5);
    hi += numtime[2];
    lo = (numtime[3] << 11);
    lo += (numtime[4] << 5);
    lo += numtime[5];
    np->n_time = (lo + ((unsigned long)hi << 16));

    if (!assign_switch) sys$dassgn(DevChan);
}

#endif


#ifdef STANDARD_MODTIME
#define MODTIME_DONE 1

#ifdef PANEWFD
VOID modtime(struct name * np)
#else
VOID modtime(np)
struct name * np;
#endif

{
    struct find_t           fi;

    if (np->n_flag & N_TSNAP) return;
    if ((np->n_name[0] == '.') && 
        (np->n_name[1] >= 'A') && 
        (np->n_name[1] <= 'Z'))
        {np->n_time = 0L; return;}

    if (_dos_findfirst(dollar(np->n_name),_A_NORMAL,&fi) != 0)
    {
#ifndef __ZTC__
        if (errno != ENOENT) fatal(MSG[75], dollar(np->n_name), errno);
#endif
        np->n_time = 0L;
    }
    else
    {
        np->n_time = ((unsigned long)fi.wr_date << 16) + (unsigned long)fi.wr_time;
    }
}

#endif

#ifndef MODTIME_DONE

#ifdef PANEWFD
VOID modtime(struct name * np)
#else
VOID modtime(np)
struct name * np;
#endif

{
    struct stat             info;
    int                     fd;

    if (np->n_flag & N_TSNAP) return;
    if ((np->n_name[0] == '.') && 
        (np->n_name[1] >= 'A') && 
        (np->n_name[1] <= 'Z'))
        {np->n_time = 0L; return;}

    if ((fd = open(dollar(np->n_name), 0)) < 0)
    {
#ifdef PAMOS2

#ifdef __BORLANDC__
        if ((errno != 0x30) &&
            (errno != ENOENT))
            fatal(MSG[76], dollar(np->n_name), _doserrno);
#endif

#ifdef MSC6
        if (errno != ENOENT) fatal(MSG[75], dollar(np->n_name), errno);
#endif

#else
        if (errno != ENOENT) fatal(MSG[75], dollar(np->n_name), errno);
#endif
        np->n_time = 0L;
    }
    else if (fstat(fd, &info) < 0)
        fatal(MSG[75], dollar(np->n_name), errno);
    else
        np->n_time = info.st_mtime;

    close(fd);
}

#endif

/*************************************************************************
|                                                                        |
|   >>>>  curtime                                                        |
|                                                                        |
|   return current system time                                           |
|                                                                        |
*************************************************************************/

#ifdef ADMAKE_FTIME

#ifdef PANEWFD
unsigned long curtime(void)
#else
unsigned long curtime()
#endif

{
    unsigned long           ct;
    struct tm *             p;   
    unsigned short          lo,hi;

#ifndef VMS
#ifndef __ZTC__
    tzset();
#endif
#endif
    time((time_t *)&ct);
    p = localtime((time_t *)&ct);
    hi = (unsigned short)((p->tm_year - 80) << 9);
    hi += (unsigned short)((p->tm_mon + 1) << 5);
    hi += (unsigned short)p->tm_mday;
    lo = (unsigned short)(p->tm_hour << 11);
    lo += (unsigned short)(p->tm_min << 5);
    lo += (unsigned short)p->tm_sec;
    return (lo + ((unsigned long)hi << 16));
}

#else

#ifdef PANEWFD
unsigned long curtime(void)
#else
unsigned long curtime()
#endif

{
    unsigned long           ct;

    time((time_t *)&ct);
    return ct;
}

#endif

/*************************************************************************
|                                                                        |
|   >>>>  touch                                                          |
|                                                                        |
|   set file time to current system time                                 |
|                                                                        |
*************************************************************************/

#ifdef VMS
#define TOUCH_DONE 1

#ifdef PANEWFD
VOID touch(struct name * np)
#else
VOID touch(np)
struct name * np;
#endif

{
    np->n_time = curtime();
    if (domake)
    {
        assign_switch = 1;
        modtime(np);
        assign_switch = 0;
    
        /* convert current time into modtime */
        sys$bintim(0,Modtime);
    
        Cdate[0] = Rdate[0] = Modtime[0];
        Cdate[1] = Rdate[1] = Modtime[1];
    
        /* note, part of the FIB was cleared by earlier QIOW, so reset it */
        Fib.fib$l_acctl = FIB$M_NORECORD;
        for (i = 0; i < 3; i++)
            Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
        for (i = 0; i < 3; i++)
            Fib.fib$w_did[i]=Nam.nam$w_did[i];
    
        /* Use the IO$_MODIFY function to change info about the file */
        /* Note, used this way, the file is not opened, however this would */
        /* normally cause the expiration and revision dates to be modified. */
        /* Using FIB$M_NORECORD prohibits this from happening. */
        status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
                            &FibDesc,&FileName,0,0,&Atr,0);
        if (!(status & 1)) fatal(MSG[78], dollar(np->n_name), status);
    
        status = iosb[0];
        if (!(status & 1)) fatal(MSG[78], dollar(np->n_name), status);
        sys$dassgn(DevChan);
    }
    if (!silent) printf(MSG[77], dollar(np->n_name));
}

#endif


#ifdef STANDARD_TOUCH
#define TOUCH_DONE 1

#ifdef PANEWFD
VOID touch(struct name * np)
#else
VOID touch(np)
struct name * np;
#endif

{
    int                     fd;
    long                    ret;

    np->n_time = ret = curtime();
    if ((fd = open(dollar(np->n_name), 0)) < 0)
    {
        if (errno != ENOENT) fatal(MSG[76], dollar(np->n_name), errno);
        np->n_time = 0L;
        return;
    }
    if (domake)
    {
        if (_dos_setftime(fd,(unsigned short)(ret >> 16),
                            (unsigned short)(ret & 0xffff)))
        {
            fatal(MSG[79],dollar(np->n_name),errno);
        }
    }
    close(fd);
    if (!silent) printf(MSG[77], dollar(np->n_name));
}

#endif

#ifndef TOUCH_DONE

#ifdef PANEWFD
VOID touch(struct name * np)
#else
VOID touch(np)
struct name * np;
#endif

{
    np->n_time = curtime();
    if (domake)
    {
        if (utime(dollar(np->n_name),0))
        {
            if (errno != ENOENT) 
                fatal(MSG[79],dollar(np->n_name),errno);
            else
            {
                fprintf(stderr,MSG[80],myname, dollar(np->n_name));
                return;
            }
        }
    }
    if (!silent) printf(MSG[77], dollar(np->n_name));
}

#endif

/*************************************************************************
|                                                                        |
|   >>>>  dodisp                                                         |
|                                                                        |
|   display file name and time                                           |
|                                                                        |
*************************************************************************/

#ifdef ADMAKE_FTIME

#ifdef PANEWFD
VOID dodisp(char * name, unsigned long t)
#else
VOID dodisp(name, t)
char * name;
unsigned long t;
#endif

{
    unsigned long u = t;

    if (t < 10) printf(MSG[93],name,t);     /* timestamp 0 */
    else 
    {
        printf(MSG[94],name);               /* timestamp */
        printf("%s %02d %02d:%02d:%02d %4d\n",
            MSG[(int)((u >> 21) & 0xf) + 80],
            (int)((u >> 16) & 0x1f),
            (int)((u >> 11) & 0x1f),
            (int)((u >> 5) & 0x3f),
            (int)(u & 0x1f),
            (int)((u >> 25) + 1980));
    }
}

#else

#ifdef PANEWFD
VOID dodisp(char * name, unsigned long t)
#else
VOID dodisp(name, t)
char * name;
unsigned long t;
#endif

{
    if (t < 10) printf(MSG[93],name,t);
    else printf(MSG[95],name,ctime((time_t *)&t));
}

#endif

/*************************************************************************
|                                                                        |
|   ALLTIME                                                              |
|                                                                        |
*************************************************************************/

#ifdef VMS
#define ALLTIME_DONE 1

#ifdef PANEWFD
VOID alltime(char * s)
#else
VOID alltime(s)
char * s;
#endif

{
    register int            i;
    int                     l;
    char                    wrk[128];
    register char *         p;
    register char *         q;
    struct name *           np;
    unsigned int            lo,hi;
    char                    temp[NAM$C_MAXRSS];

    strncpy(wrk,s,127);
    wrk[127] = '\0';

    l = strlen(wrk);
    p = wrk + l - 1;
    while ((*p != ']') && (*p != ':') && (p >= wrk)) *p-- = '\0';
    p++;

    /* initialize RMS structures, we need a NAM to retrieve the FID */
    Fab = cc$rms_fab;
    Fab.fab$l_fna = s;
    Fab.fab$b_fns = strlen(s);
    Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
    Nam = cc$rms_nam;
    Nam.nam$l_esa = &EName; /* expanded filename */
    Nam.nam$b_ess = sizeof(EName);
    Nam.nam$l_rsa = &RName; /* resultant filename */
    Nam.nam$b_rss = sizeof(RName);

    status = sys$parse(&Fab);
    if (!(status & 1)) return;
    
    while (1)
    {
        status = sys$search(&Fab);
        if (status == RMS$_NMF) break;      /* no more files */
        if (status == RMS$_FNF) 
        {
            Fab.fab$b_dns = 0;
            Nam.nam$l_rlf = 0;
            Nam.nam$b_nop |= NAM$M_SYNCHK;
            sys$parse(&Fab);
            break;              /* (first) file not found */
        }
        
        if (!(status & 1)) return;          /* call failed */
        if (Nam.nam$l_fnb & NAM$M_HIGHVER)  /* higher version(s) exist */
            continue;                       /* so forget this one */
        if (!(status & 1)) break;

        for (i = 0; i < Nam.nam$b_rsl; i++) 
           temp[i] = Nam.nam$l_rsa[i];

        q = temp;
        *(q + Nam.nam$b_rsl) = '\0';        /* ensure null-terminated */
        for (i = 0; i < Nam.nam$b_rsl; i++) 
           if (temp[i] == ']') break;
        if (i >= Nam.nam$b_rsl) continue;   /* no ']' in expanded name */
        q = temp + i + 1;
        for (l = i; l < Nam.nam$b_rsl; l++) 
           if (temp[l] == ';') {temp[l] = '\0'; break;}

        for (i = 0; ; i++)
        {
            if ((q[i] >= 'A') && (q[i] <= 'Z')) p[i] = q[i] + 'a' - 'A';
            else if ((p[i] = q[i]) == '\0') break;
        }

        /* initialize Device name length, note that this points into the NAM
           to get the device name filled in by the $PARSE, $SEARCH services */
        DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
    
        status = sys$assign(&DevDesc,&DevChan,0,0);
        if (!(status & 1)) return;
    
        FileName.dsc$a_pointer = Nam.nam$l_name;
        FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
    
        /* Initialize the FIB */
        for (i = 0; i < 3; i++)
            Fib.fib$w_fid[i]=Nam.nam$w_fid[i];
        for (i = 0; i < 3; i++)
            Fib.fib$w_did[i]=Nam.nam$w_did[i];
    
        /* Use the IO$_ACCESS function to return info about the file */
        /* Note, used this way, the file is not opened, and the expiration */
        /* and revision dates are not modified */
        status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
                            &FibDesc,&FileName,0,0,&Atr,0);
        if (!(status & 1)) return;
        status = iosb[0];
        if (!(status & 1)) return;
    
        Modtime[0] = Cdate[0];
        Modtime[1] = Cdate[1];
        if ((Rdate[0] == 0) && (Rdate[1] == 0))
        {
            Modtime[0] = Rdate[0];
            Modtime[1] = Rdate[1];
        }   
        if ((Modtime[0] == 0) && (Modtime[1] == 0)) {np->n_time = 0L; return;}
    
        /* convert Modtime to np->ntime (dos format) */
        sys$numtim(numtime,Modtime);
        hi = (numtime[0] - 1980) << 9;
        hi += (numtime[1] << 5);
        hi += numtime[2];
        lo = (numtime[3] << 11);
        lo += (numtime[4] << 5);
        lo += numtime[5];

        np = newname(wrk);
        np->n_flag |= N_TSNAP;
        np->n_time = (lo + ((unsigned long)hi << 16));
    
        sys$dassgn(DevChan);
    }
}
#endif


#ifdef STANDARD_ALLTIME
#define ALLTIME_DONE 1

#ifdef PANEWFD
VOID alltime(char * s)
#else
VOID alltime(s)
char * s;
#endif

{
    struct find_t           fi;
    int                     l;
    char                    wrk[128];
    register char *         p;
    struct name *           np;

    if (_dos_findfirst(dollar(s),_A_NORMAL,&fi) != 0) return;

    strncpy(wrk,s,127);
    wrk[127] = '\0';

    l = strlen(wrk);
    p = wrk + l - 1;
    while ((*p != '\\') && (*p != '/') && (*p != ':') && (p >= wrk)) *p-- = '\0';
    p++;
    do
    {
        strcpy(p,strlwr(fi.name));
        np = newname(wrk);
        np->n_time = ((unsigned long)fi.wr_date << 16) + (unsigned long)fi.wr_time;
        np->n_flag |= N_TSNAP;
    } while (_dos_findnext(&fi) == 0);
}

#endif 


#ifndef ALLTIME_DONE

#ifdef PANEWFD
VOID alltime(char * s)
#else
VOID alltime(s)
char * s;
#endif

{
    ;
}

#endif

